import { InitRMB } from './Const';
import { PlayerType, BuildingType } from './Enums';
import { BuildingModel, FailCommandModel, UnitModel } from './Model';

/**
 * 战斗玩家数据类
 * 管理玩家的基本信息和战斗统计数据
 */
export class BattlePlayer {
    // 基本属性
    private _id: string;
    private _playerType: PlayerType;
    private _color: string;
    private _startPosition: { x: number; y: number };
    private rmb: number = InitRMB;  // 玩家资源（人民币）

    // 单位和建筑管理
    private units: Map<number, UnitModel> = new Map();
    private buildings: Map<number, BuildingModel> = new Map();

    // 玩家统计数据
    private totalDamageDealt: number = 0;          // 造成的总伤害
    private totalDamageReceived: number = 0;       // 受到的总伤害
    private totalHealing: number = 0;              // 治疗总量
    private kills: number = 0;                     // 击杀数
    private deaths: number = 0;                    // 死亡数

    private failedCommands: FailCommandModel[] = [];            // 失败的命令列表
    private codeExecutionFailCount: number = 0;                 // 代码执行异常计数

    constructor(id: string, playerType: PlayerType, color: string, startPosition: { x: number; y: number }) {
        this._id = id;
        this._playerType = playerType;
        this._color = color;
        this._startPosition = startPosition;
    }

    /**
     * 获取玩家ID
     */
    public getId(): string {
        return this._id;
    }

    /**
     * 获取玩家类型
     */
    public getPlayerType(): PlayerType {
        return this._playerType;
    }

    /**
     * 获取玩家颜色
     */
    public getColor(): string {
        return this._color;
    }

    /**
     * 获取玩家出生位置
     */
    public getStartPosition(): { x: number; y: number } {
        return this._startPosition;
    }

    /**
     * 判断是否为左侧玩家（玩家1）
     */
    public isLeftSidePlayer(): boolean {
        return this._playerType === PlayerType.PLAYER1;
    }

    /**
     * 判断是否为右侧玩家（玩家2）
     */
    public isRightSidePlayer(): boolean {
        return this._playerType === PlayerType.PLAYER2;
    }

    /**
     * 添加单位
     * @param unit 单位模型
     */
    public addUnit(unit: UnitModel): void {
        this.units.set(unit.id, unit);
    }

    /**
     * 添加建筑
     * @param building 建筑模型
     */
    public addBuilding(building: BuildingModel): void {
        this.buildings.set(building.id, building);
    }

    /**
     * 获取单位
     * @param unitId 单位ID
     */
    public getUnit(unitId: number): UnitModel | undefined {
        return this.units.get(unitId);
    }

    /**
     * 获取建筑
     * @param buildingId 建筑ID
     */
    public getBuilding(buildingId: number): BuildingModel | undefined {
        return this.buildings.get(buildingId);
    }

    /**
     * 获取所有单位
     */
    public getAllUnits(): UnitModel[] {
        return Array.from(this.units.values());
    }

    /**
     * 获取所有建筑
     */
    public getAllBuildings(): BuildingModel[] {
        return Array.from(this.buildings.values());
    }

    /**
     * 获取pos位置上的单位
     */
    public getUnitAt(position: { x: number, y: number }): UnitModel | undefined {
        for (let unit of this.units.values()) {
            if (unit.position.x === position.x && unit.position.y === position.y) {
                return unit;
            }
        }
        return undefined
    }

    /**
     * 获取pos位置上的建筑
     */
    public getBuildingAt(position: { x: number, y: number }): BuildingModel | undefined {
        for (let building of this.buildings.values()) {
            if (building.position.x === position.x && building.position.y === position.y) {
                return building;
            }
        }
        return undefined
    }

    /**
     * 移除单位（标记为死亡）
     * @param unitId 单位ID
     */
    public removeUnit(unitId: number): boolean {
        const unit = this.units.get(unitId);
        if (unit) {
            return this.units.delete(unitId);
        }
        return false;
    }

    /**
     * 移除建筑（标记为被摧毁）
     * @param buildingId 建筑ID
     */
    public removeBuilding(buildingId: number): boolean {
        const building = this.buildings.get(buildingId);
        if (building) {
            return this.buildings.delete(buildingId);
        }
        return false;
    }

    /**
     * 更新单位状态
     * @param unitId 单位ID
     * @param hp 血量
     */
    public updateUnitHealth(unitId: number, hp: number): void {
        const unit = this.units.get(unitId);
        if (unit) {
            unit.hp = hp;
            if (hp <= 0) {
                this.removeUnit(unitId);
            }
        }
    }

    /**
     * 更新建筑状态
     * @param buildingId 建筑ID
     * @param hp 血量
     */
    public updateBuildingHealth(buildingId: number, hp: number): void {
        const building = this.buildings.get(buildingId);
        if (building) {
            building.hp = hp;

            if (hp <= 0) {
                this.removeBuilding(buildingId);
            }
        }
    }

    /**
     * 获取存活单位数量
     */
    public getAliveUnitsCount(): number {
        return this.units.size;
    }

    /**
     * 获取现存建筑数量
     */
    public getExistingBuildingsCount(): number {
        return this.buildings.size;
    }

    /**
     * 重置统计数据
     */
    public resetStats(): void {
        this.units.clear();
        this.buildings.clear();
        this.deaths = 0;
        this.totalDamageDealt = 0;
        this.totalDamageReceived = 0;
        this.totalHealing = 0;
        this.kills = 0;
        this.rmb = 0;
        this.failedCommands = [];
        this.codeExecutionFailCount = 0;
    }

    /**
     * 获取造成的总伤害
     */
    public getTotalDamageDealt(): number {
        return this.totalDamageDealt;
    }

    /**
     * 获取受到的总伤害
     */
    public getTotalDamageReceived(): number {
        return this.totalDamageReceived;
    }

    /**
     * 获取治疗总量
     */
    public getTotalHealing(): number {
        return this.totalHealing;
    }

    /**
     * 获取击杀数
     */
    public getKills(): number {
        return this.kills;
    }

    /**
     * 添加造成的伤害
     * @param damage 伤害值
     */
    public addDamageDealt(damage: number): void {
        this.totalDamageDealt += damage;
    }

    /**
     * 添加受到的伤害
     * @param damage 伤害值
     */
    public addDamageReceived(damage: number): void {
        this.totalDamageReceived += damage;
    }

    /**
     * 添加治疗量
     * @param healing 治疗值
     */
    public addHealing(healing: number): void {
        this.totalHealing += healing;
    }

    /**
     * 添加击杀数
     */
    public addKill(): void {
        this.kills++;
    }

    /**
     * 获取死亡次数
     */
    public getDeaths(): number {
        return this.deaths;
    }

    /**
     * 添加死亡次数
     */
    public addDeath(): void {
        this.deaths++;
    }

    /**
     * 获取玩家资源（人民币）
     */
    public getRmb(): number {
        return this.rmb;
    }

    /**
     * 添加玩家资源（人民币）
     * @param value 资源值
     */
    public addRmb(value: number): void {
        this.rmb += value;
    }

    /**
     * 获取命令失败次数
     */
    public getCommandFailCount(): number {
        return this.failedCommands.length;
    }

    /**
     * 添加失败的命令
     * @param command 失败的命令
     */
    public addFailedCommand(command: FailCommandModel): void {
        this.failedCommands.push(command);
    }

    /**
     * 获取所有失败的命令
     */
    public getFailedCommands(): FailCommandModel[] {
        return this.failedCommands;
    }

    /**
     * 清空失败的命令列表
     */
    public clearFailedCommands(): void {
        this.failedCommands = [];
    }

    /**
     * 获取基地血量
     */
    public getBaseHealth(): number {
        const baseBuilding = Array.from(this.buildings.values()).find(building => building.type === BuildingType.base);
        return baseBuilding ? baseBuilding.hp : 0;
    }

    /**
     * 获取代码执行异常次数
     */
    public getCodeExecutionFailCount(): number {
        return this.codeExecutionFailCount;
    }

    /**
     * 增加代码执行异常次数
     */
    public addCodeExecutionFail(): void {
        this.codeExecutionFailCount++;
    }

    /**
     * 重置代码执行异常次数
     */
    public resetCodeExecutionFailCount(): void {
        this.codeExecutionFailCount = 0;
    }
}